import { reroute } from "./reroute.js";
export const routingEventsListeningTo = ["hashchange", "popstate"];
const capturedEventListeners = { // 存储hashchang和popstate注册的方法
    hashchange: [],
    popstate: []
}
function urlReroute() {
    reroute([], arguments)
}
// 劫持路由变化
window.addEventListener('hashchange', urlReroute); 
window.addEventListener('popstate', urlReroute);
// 重写addEventListener方法
const originalAddEventListener = window.addEventListener;
const originalRemoveEventListener = window.removeEventListener;

window.addEventListener = function(eventName, fn) {
    if (routingEventsListeningTo.indexOf(eventName) >= 0 && !capturedEventListeners[eventName].some(listener => listener == fn)) {
        capturedEventListeners[eventName].push(fn);
        return;
    }
    return originalAddEventListener.apply(this, arguments);
}
window.removeEventListener = function(eventName, listenerFn) {
    if (routingEventsListeningTo.indexOf(eventName) >= 0) {
        capturedEventListeners[eventName] = capturedEventListeners[
            eventName
        ].filter((fn) => fn !== listenerFn);
        return;
    }
    return originalRemoveEventListener.apply(this, arguments);
};
function patchedUpdateState(updateState, methodName) {
    return function() {
        const urlBefore = window.location.href;
        const result = updateState.apply(this, arguments);
        const urlAfter = window.location.href;
        if (urlBefore !== urlAfter) {
            urlReroute(new PopStateEvent('popstate', { state }));
        }
        return result;
    }
}
// 重写pushState 和 repalceState方法
window.history.pushState = patchedUpdateState(window.history.pushState, 'pushState');
window.history.replaceState = patchedUpdateState(window.history.replaceState, 'replaceState');

// 在子应用加载完毕后调用此方法，执行拦截的逻辑（保证子应用加载完后执行）
export function callCapturedEventListeners(eventArguments) {
    if (eventArguments) {
        const eventType = eventArguments[0].type;
        if (routingEventsListeningTo.indexOf(eventType) >= 0) {
            capturedEventListeners[eventType].forEach((listener) => {
                listener.apply(this, eventArguments);
            });
        }
    }
}